<?php
/**
 * 综合API测试脚本
 * 用于全面测试OA系统的所有API接口
 */

require_once 'vendor/autoload.php';

class ComprehensiveApiTester
{
    private $baseUrl = 'http://localhost:8000';
    private $username = 'liuhui';
    private $password = 'zhilv2023';
    private $token = null;
    private $userInfo = null;
    private $testResults = [];
    
    // 统计信息
    private $totalTests = 0;
    private $passedTests = 0;
    private $failedTests = 0;

    public function __construct()
    {
        echo "========================================\n";
        echo "开始综合API测试\n";
        echo "========================================\n";
    }

    /**
     * 发送HTTP请求
     */
    private function request($method, $uri, $data = [], $headers = [])
    {
        $url = $this->baseUrl . $uri;
        
        // 添加认证头
        if ($this->token) {
            $headers['Authorization'] = 'Bearer ' . $this->token;
        }
        
        // 添加内容类型头
        if (!isset($headers['Content-Type']) && in_array($method, ['POST', 'PUT', 'PATCH'])) {
            $headers['Content-Type'] = 'application/json';
        }

        $curl = curl_init();
        
        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $this->buildHeaders($headers),
            CURLOPT_TIMEOUT => 30,
        ]);
        
        if (!empty($data) && in_array($method, ['POST', 'PUT', 'PATCH'])) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
        }
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        
        curl_close($curl);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("JSON decode error: " . json_last_error_msg());
        }
        
        return [
            'status_code' => $httpCode,
            'data' => $result,
            'raw' => $response
        ];
    }

    /**
     * 构建HTTP头
     */
    private function buildHeaders($headers)
    {
        $result = [];
        foreach ($headers as $key => $value) {
            $result[] = $key . ': ' . $value;
        }
        return $result;
    }

    /**
     * 记录测试结果
     */
    private function recordTest($name, $passed, $details = '')
    {
        $this->totalTests++;
        if ($passed) {
            $this->passedTests++;
            echo "✓ " . $name . ($details ? " - " . $details : "") . "\n";
        } else {
            $this->failedTests++;
            echo "✗ " . $name . ($details ? " - " . $details : "") . "\n";
        }
        
        $this->testResults[] = [
            'name' => $name,
            'passed' => $passed,
            'details' => $details
        ];
    }

    /**
     * 测试用户登录
     */
    public function testLogin()
    {
        echo "\n[认证模块测试]\n";
        
        // 测试正常登录
        try {
            $response = $this->request('POST', '/api/auth/login', [
                'username' => $this->username,
                'password' => $this->password
            ]);
            
            if ($response['status_code'] === 200 && isset($response['data']['code']) && $response['data']['code'] === 0) {
                $this->token = $response['data']['data']['token'];
                $this->userInfo = $response['data']['data']['userInfo'];
                $this->recordTest('用户正常登录', true, 'Token: ' . substr($this->token, 0, 10) . '...');
            } else {
                $this->recordTest('用户正常登录', false, '响应: ' . $response['raw']);
            }
        } catch (Exception $e) {
            $this->recordTest('用户正常登录', false, '异常: ' . $e->getMessage());
        }
        
        // 测试空用户名密码
        try {
            $response = $this->request('POST', '/api/auth/login', [
                'username' => '',
                'password' => ''
            ]);
            
            if ($response['status_code'] === 200 && isset($response['data']['code']) && $response['data']['code'] === 1) {
                $this->recordTest('空用户名密码登录', true, $response['data']['msg']);
            } else {
                $this->recordTest('空用户名密码登录', false, '响应未正确处理');
            }
        } catch (Exception $e) {
            $this->recordTest('空用户名密码登录', false, '异常: ' . $e->getMessage());
        }
        
        // 测试不存在的用户
        try {
            $response = $this->request('POST', '/api/auth/login', [
                'username' => 'nonexistentuser',
                'password' => 'wrongpassword'
            ]);
            
            if ($response['status_code'] === 200 && isset($response['data']['code']) && $response['data']['code'] === 1) {
                $this->recordTest('不存在用户登录', true, $response['data']['msg']);
            } else {
                $this->recordTest('不存在用户登录', false, '响应未正确处理');
            }
        } catch (Exception $e) {
            $this->recordTest('不存在用户登录', false, '异常: ' . $e->getMessage());
        }
        
        // 测试错误密码
        try {
            $response = $this->request('POST', '/api/auth/login', [
                'username' => $this->username,
                'password' => 'wrongpassword'
            ]);
            
            if ($response['status_code'] === 200 && isset($response['data']['code']) && $response['data']['code'] === 1) {
                $this->recordTest('错误密码登录', true, $response['data']['msg']);
            } else {
                $this->recordTest('错误密码登录', false, '响应未正确处理');
            }
        } catch (Exception $e) {
            $this->recordTest('错误密码登录', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 测试主接口
     */
    public function testMainApis()
    {
        if (!$this->token) {
            echo "\n[主接口测试] - 跳过（需要先登录）\n";
            return;
        }
        
        echo "\n[主接口测试]\n";
        
        // 测试首页接口
        try {
            $response = $this->request('GET', '/api/index/index');
            if ($response['status_code'] === 200) {
                $this->recordTest('首页接口', true);
            } else {
                $this->recordTest('首页接口', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('首页接口', false, '异常: ' . $e->getMessage());
        }
        
        // 测试审批接口
        try {
            $response = $this->request('GET', '/api/check/index');
            if ($response['status_code'] === 200) {
                $this->recordTest('审批接口', true);
            } else {
                $this->recordTest('审批接口', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('审批接口', false, '异常: ' . $e->getMessage());
        }
        
        // 测试演示接口
        try {
            $response = $this->request('GET', '/api/demo/index');
            if ($response['status_code'] === 200) {
                $this->recordTest('演示接口', true);
            } else {
                $this->recordTest('演示接口', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('演示接口', false, '异常: ' . $e->getMessage());
        }
        
        // 测试办公接口
        try {
            $response = $this->request('GET', '/api/office/index');
            if ($response['status_code'] === 200) {
                $this->recordTest('办公接口', true);
            } else {
                $this->recordTest('办公接口', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('办公接口', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 测试导入接口
     */
    public function testImportApis()
    {
        if (!$this->token) {
            echo "\n[导入接口测试] - 跳过（需要先登录）\n";
            return;
        }
        
        echo "\n[导入接口测试]\n";
        
        try {
            $response = $this->request('GET', '/api/import/index');
            if ($response['status_code'] === 200) {
                $this->recordTest('导入首页接口', true);
            } else {
                $this->recordTest('导入首页接口', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('导入首页接口', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 测试合同管理接口
     */
    public function testContractApis()
    {
        if (!$this->token) {
            echo "\n[合同管理接口测试] - 跳过（需要先登录）\n";
            return;
        }
        
        echo "\n[合同管理接口测试]\n";
        
        // 测试获取合同列表
        try {
            $response = $this->request('POST', '/contract/api/get_contract', [
                'page' => 1,
                'limit' => 10
            ]);
            
            if ($response['status_code'] === 200) {
                $this->recordTest('获取合同列表', true);
            } else {
                $this->recordTest('获取合同列表', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('获取合同列表', false, '异常: ' . $e->getMessage());
        }
        
        // 测试搜索合同
        try {
            $response = $this->request('POST', '/contract/api/get_contract', [
                'page' => 1,
                'limit' => 10,
                'keywords' => '合同'
            ]);
            
            if ($response['status_code'] === 200) {
                $this->recordTest('搜索合同', true);
            } else {
                $this->recordTest('搜索合同', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('搜索合同', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 测试客户管理接口
     */
    public function testCustomerApis()
    {
        if (!$this->token) {
            echo "\n[客户管理接口测试] - 跳过（需要先登录）\n";
            return;
        }
        
        echo "\n[客户管理接口测试]\n";
        
        // 测试获取客户列表
        try {
            $response = $this->request('POST', '/customer/api/get_customer', [
                'page' => 1,
                'limit' => 10
            ]);
            
            if ($response['status_code'] === 200) {
                $this->recordTest('获取客户列表', true);
            } else {
                $this->recordTest('获取客户列表', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('获取客户列表', false, '异常: ' . $e->getMessage());
        }
        
        // 测试搜索客户
        try {
            $response = $this->request('POST', '/customer/api/get_customer', [
                'page' => 1,
                'limit' => 10,
                'keywords' => '客户'
            ]);
            
            if ($response['status_code'] === 200) {
                $this->recordTest('搜索客户', true);
            } else {
                $this->recordTest('搜索客户', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('搜索客户', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 测试财务管理接口
     */
    public function testFinanceApis()
    {
        if (!$this->token) {
            echo "\n[财务管理接口测试] - 跳过（需要先登录）\n";
            return;
        }
        
        echo "\n[财务管理接口测试]\n";
        
        // 测试获取发票列表
        try {
            $response = $this->request('GET', '/finance/api/get_invoice');
            if ($response['status_code'] === 200) {
                $this->recordTest('获取发票列表', true);
            } else {
                $this->recordTest('获取发票列表', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('获取发票列表', false, '异常: ' . $e->getMessage());
        }
        
        // 测试获取报销列表
        try {
            $response = $this->request('GET', '/finance/api/get_expense');
            if ($response['status_code'] === 200) {
                $this->recordTest('获取报销列表', true);
            } else {
                $this->recordTest('获取报销列表', false, '状态码: ' . $response['status_code']);
            }
        } catch (Exception $e) {
            $this->recordTest('获取报销列表', false, '异常: ' . $e->getMessage());
        }
    }

    /**
     * 生成测试报告
     */
    public function generateReport()
    {
        echo "\n========================================\n";
        echo "测试报告\n";
        echo "========================================\n";
        echo "总测试数: " . $this->totalTests . "\n";
        echo "通过测试: " . $this->passedTests . "\n";
        echo "失败测试: " . $this->failedTests . "\n";
        echo "通过率: " . ($this->totalTests > 0 ? round(($this->passedTests / $this->totalTests) * 100, 2) : 0) . "%\n";
        
        if ($this->failedTests > 0) {
            echo "\n失败的测试:\n";
            foreach ($this->testResults as $result) {
                if (!$result['passed']) {
                    echo "- " . $result['name'] . ": " . $result['details'] . "\n";
                }
            }
        }
        
        echo "\n";
    }

    /**
     * 运行所有测试
     */
    public function run()
    {
        $startTime = microtime(true);
        
        // 运行各类测试
        $this->testLogin();
        $this->testMainApis();
        $this->testImportApis();
        $this->testContractApis();
        $this->testCustomerApis();
        $this->testFinanceApis();
        
        $endTime = microtime(true);
        $executionTime = round(($endTime - $startTime) * 1000, 2);
        
        // 生成报告
        $this->generateReport();
        
        echo "执行时间: " . $executionTime . " 毫秒\n";
        echo "测试完成时间: " . date('Y-m-d H:i:s') . "\n";
        
        return $this->failedTests === 0;
    }
}

// 运行测试
$tester = new ComprehensiveApiTester();
exit($tester->run() ? 0 : 1);